#!/usr/bin/perl
#
# Write the report of registered machines
#
# Bar-graphs added by denis&#x40;havlik.org (12/1999) 
#
use strict;
use lib '/home/counter/base/lib';
require "reportsub.pl";
use Validate::Machines;
use vars qw(%numbers $validate $html);
use vars qw($machinefile %machines %machinesums);
use vars qw(%total %count %average %minimum %maximum);
#===================== CONFIGURATION ==================

# disk is "high" when passing 3 Terabyte.

my %numbers = (
"disk", [0,1,3,10,30,100,300,
         1000,3000,  # 1 Gbyte
         10000,30000,
         100000,300000,
         1000000,3000000],   # 1 Tbyte
"accounts",[0,1,2,3,4,5,10,25,50,100,250,500,1000,2500,5000,10000,15000,20000,25000,30000,35000,40000,45000,50000,75000,100000],
"users", [0,1,2,3,4,5,10,25,50,100,250,500,1000,2500,5000,10000,15000,20000,25000,30000,35000,40000,45000,50000,75000,100000],
"memory", [0,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536],
	    );
#
#  Change these variables to tweak the look of the tables
#

# only data which account for more than 100*$TRESHOLD % 
# of the total are shown.
#my $TRESHOLD=0.01/100;
#my $TRESHOLD=0.01; # 1%
my $TRESHOLD=0.005; # 0.5%
# width of the 1% bar in pixels
my $BAR_WIDTH=3;
my $BAR_HEIGHT = 20;

while ($ARGV[0] =~ /^-/) {
    my $opt = shift;
    if ($opt eq "-validate") {
	# Force revalidation of values.
	# Used as a test tool on the validation routines.
	$validate = 1;
    } elsif ($opt eq "-html") {
	$html = 1;
    }
}

$machinefile = shift;
$machinefile = "machines.count" if !$machinefile;

#===================== DATA FETCH =======================

readfile($machinefile, \%machines, \%machinesums);

#===================== REVALIDATE =======================

if ($validate) {
    my $val = new Validate::Machines;
    my $field;
    for $field (keys(%machines)) {
	my $interesting = $machinesums{$field}{total} * $TRESHOLD;
	my $value;
	for $value (keys(%{$machines{$field}})) {
	    my $new = $val->cleanfield($field, $value);
	    my $count = $machines{$field}{$value};
	    if ($new ne $value) {
		# Point out changes in validation routines
		print STDERR "$field: $value changed to $new\n";
		$machines{$field}{$new} += $machines{$field}{$value};
		delete $machines{$field}{$value};
	    } elsif ($count > 1 &&
		     $count < $interesting && !$numbers{$field}) {
		# Things that occur rarely ought to be checked,
		# but single occurences are just speling misteaks
		# Numbers can't be warned this way!
		print STDERR "$field: Clean($count) $value\n";
	    }
	}
    }
}

#============ NUMBER PROCESSING ==============
my $field;
for $field (keys(%numbers)) {
    warn "Numeric processing for $field\n";
    my %newval;
    my $toobigcount = 0;
    my @numlist = @{$numbers{$field}};
    # guard against empty fields...
    next if $#numlist == -1;
    my $value;
    for $value (keys(%{$machines{$field}})) {
	if ($value <= $numlist[$#numlist]) {
	    $total{$field} += $value * $machines{$field}{$value};
	} else {
	    ++ $toobigcount;
	}
	$count{$field} += $machines{$field}{$value};
	$minimum{$field} = $value
	    if !$minimum{$field} || $minimum{$field} > $value;
	$maximum{$field} = $value if $maximum{$field} < $value
	    && $value <= $numlist[$#numlist];
	my $newv = "Too big";
        my $scan;
	for $scan (1..$#numlist) {
	    if ($value < $numlist[$scan]) {
		if ($numlist[$scan-1] + 1 == $numlist[$scan]) {
		    $newv = sprintf("%5d", $numlist[$scan-1]);
		} else {
		    $newv = sprintf("%6d-%-6d",
				$numlist[$scan-1], $numlist[$scan]-1);
		}
		last;
	    }
	}
	$newval{$newv} += $machines{$field}{$value};
    }
    if ($count{$field} != $machinesums{$field}{values}) {
	print STDERR "$field: count $count{$field} total $machinesums{$field}{values}\n";
    }
    if (($machinesums{$field}{values} - $toobigcount) > 0) {
	$average{$field} = $total{$field} / 
	    ($machinesums{$field}{values} - $toobigcount);
    } else {
	$average{$field} = 0;
    }
    $machines{$field} = \%newval;
#    undef %{$machines{$field}};
#    for $v (keys(%newval)) {
#	$machines{$field}{$v} = $newval{$v};
#    }
#    undef %newval;
}

#================ REPORT =====================

if ($html) {
    htmlreport();
} else {
    textreport();
}
sub textreport {
    for $field (sort(keys(%machines))) {
	my $others = 0;
        my $tfield = $field;
	my $interesting = $machinesums{$field}{total} * $TRESHOLD;
	print "$field\n";
	print "=" x length($field), "\n";
	printf "%5d %s\n", $machinesums{$field}{total}, "reported";
	printf "%5d %s\n", $machinesums{$field}{values}, "values";
	if ($numbers{$field}) {
	    printf "%-7s %5d\n", "Average", $average{$field};
	    printf "%-7s %5d\n", "Minimum", $minimum{$field};
	    printf "%-7s %5d\n", "Maximum", $maximum{$field};
	}
	my $value;
	if ($machinesums{$field}{total} > 0) {
          # Order numerical $value fields, eventually with a - in the field
          if ($tfield eq "accounts" || $tfield eq "disk" || $tfield eq "memory" || $tfield eq "users") {
            for $value (sort {$a <=> $b} (keys(%{$machines{$field}}))) {
		my $count = $machines{$field}{$value};
		if ($count > $interesting) {
		    printf "%6d %6.2f%% %s: %s\n",
		    $count, $count*100/$machinesums{$field}{total}, $field, $value;
		} else {
		    $others += $count;
		}
            }
	  } else {
            # Real alphabetical ordering of $value fields
            for $value (sort(keys(%{$machines{$field}}))) {
                my $count = $machines{$field}{$value};
                if ($count > $interesting) {
                   printf "%6d %6.2f%% %s: %s\n",
                   $count, $count*100/$machinesums{$field}{total}, $field, $value;
                } else {
                   $others += $count;
                }
            }
          }
	  printf "%6d %6.2f%% %s: %s\n\n", $others,
	  $others*100/$machinesums{$field}{total}, $field, "Others";
	} else {
	  print "No registered values for $field\n\n";
	}
    }
}

sub htmlreport {

    my $date = localtime();

    print <<EoF;
<?php
 include "counter.php";
?>
<?php pagehead("Linux Counter Machine Report") ?>
<BODY bgcolor="white">
<?php pagetop() ?>
<h1><img src="/gifs/Logo-small.png">
Linux Counter Machine Report</h1>
Generated: $date<br><br>
Only counts greater than or equal to 0.5% of the total number of values entered are shown. Counts less than 0.5% are counted together and represented as <b>Others</b> in the tables.
EoF

    for $field (sort(keys(%machines))) {
      my $others = 0;
      my $pfield = $field;
      my $interesting = $machinesums{$field}{total} * $TRESHOLD;
      if ($field =~ /\//) {
	  $pfield =~ s/\///;
	  print "<h2>\u$pfield (Summarized)</h2>\n";
      } else {
	  print "<h2>\u$field</h2>\n";
      }
      print "$machinesums{$field}{total} registrations entered", "
                 $machinesums{$field}{values} values\n";
      if ($numbers{$field}) {
	print "<table>\n";
	printf "<tr><td>%-7s</td><td> %5d</tr>\n", "Average", $average{$field};
	printf "<tr><td>%-7s</td><td> %5d</tr>\n", "Minimum", $minimum{$field};
	printf "<tr><td>%-7s</td><td> %5d</tr>\n", "Maximum", $maximum{$field};
	print "</table>\n";
      }
      print "<table border>\n";
      print "<tr><th>$pfield</th><th>Count</th><th colspan=2>Percent</th></tr>\n";
      
      my $value;
        # Order numerical $value fields, eventually with a - in the field
        if ($pfield eq "accounts" || $pfield eq "disk" || $pfield eq "memory" || $pfield eq "users") {
	  for $value (sort {$a <=> $b} (keys(%{$machines{$field}}))) {
	    my $count = $machines{$field}{$value};
	    if ($count > $interesting) {
	      my $perc= $count*100.0/$machinesums{$field}{total};
	      &add_row($value, $count, $perc);
	    } else {
		$others += $count;
	    }
	  }
        } else {
          # Real alphabetical ordering of $value fields
          for $value (sort(keys(%{$machines{$field}}))) {
            my $count = $machines{$field}{$value};
            if ($count > $interesting) {
              my $perc= $count*100.0/$machinesums{$field}{total};
              &add_row($value, $count, $perc);
            } else {
              $others += $count;
            }
          }
        }
      if ($machinesums{$field}{total} > 0) {
	  &add_row("Others", $others, $others*100/$machinesums{$field}{total});
      }
      print "</table>\n";
    }
    print "<?php pagebottom() ?>\n";
    print "</body></html>\n";
}

sub add_row {
  my ($value, $count, $perc) = @_;
  # bar width must be at least 1, or it looks really ugly.
  my $bar=$perc*$BAR_WIDTH+1;      

  printf "<tr><td>%s</td><td align=right>%5d </td><td align = right>%6.2f%%</td>\n\t" , $value, $count, $perc;
  printf "<td align=left><img SRC=\"bar.gif\" HSPACE=5 BORDER=0 height=%d width=%f align=LEFT></td></tr>\n", $BAR_HEIGHT, $bar; 
}
  
